/*
Copyright (C) 2022-2024 Inspur Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/
package service

import (
	"did-service/bean/entity"
	"did-service/bean/param"
	"did-service/common/constant"
	"did-service/common/uuid"
	"time"
)

// FindPubKeyByDid 根据did查找公钥
func (ds *DidService) FindPubKeyByDid(did string) (string, bool, error) {
	var (
		key  = did + constant.DefaultKey1Subfix
		find string
	)
	ok, err := ds.engine.Table("did_document_key").
		Where("key_id = ?", key).
		Cols("pub_key").Get(&find)
	return find, ok, err
}

// FindPrvKeyByDid 根据did查找私钥
func (ds *DidService) FindPrvKeyByDid(did string) (string, bool, error) {
	var (
		key  = did + constant.DefaultKey1Subfix
		find string
	)
	ok, err := ds.engine.Table("did_document_key").
		Where("key_id = ?", key).
		Cols("prv_key").Get(&find)
	return find, ok, err
}

// CreateCredentialGrant 添加一条授权记录
func (ds *DidService) CreateCredentialGrant(grantId, walletId string, grantParam *param.CredentialGrant,
	rk, encryptRk, entryType, signature string) error {
	var (
		grantDate      time.Time
		expirationDate time.Time
		err            error
	)

	if grantDate, err = parseTime(grantParam.CreateDate); err != nil {
		return err
	}
	if expirationDate, err = parseTime(grantParam.Exp); err != nil {
		return err
	}
	grantTable := &entity.CredentialGrant{
		OwnerDid:       grantParam.Owner,
		Grantee:        grantParam.Grantee,
		ObjectId:       grantParam.ObjectId,
		Allow:          grantParam.Allow,
		GrantDate:      grantDate,
		ExpirationDate: expirationDate,
		Signature:      signature,
		Secret:         rk,
		EncryptSecret:  encryptRk,
		EncryptType:    entryType,
		UpdatedTime:    time.Now(),
		OwnerId:        walletId,
	}
	if len(grantId) == 0 {
		grantTable.Id = uuid.Generate()
		grantTable.CreatedTime = time.Now()
		_, err = ds.engine.InsertOne(grantTable)
	} else {
		_, err = ds.engine.Id(grantId).Update(grantTable)
	}
	return err
}

// GetCredentialGrantVerify 根据凭证id和授权人查找授权的验证数据
func (ds *DidService) GetCredentialGrantVerify(objectId, grantee string) (*entity.CredentialGrant, bool) {
	var grant entity.CredentialGrant
	grant.ObjectId = objectId
	grant.Grantee = grantee
	ok, err := ds.engine.Cols("allow", "grant_date", "expiration_date", "secret").
		Get(&grant)
	if err != nil {
		log.Errorf("get grant error %s", err.Error())
		return nil, false
	}
	if !ok {
		return nil, false
	}
	return &grant, true
}

// GetCredentialGrantCreate 根据凭证id和授权人查找授权前的校验数据
func (ds *DidService) GetCredentialGrantCreate(objectId, grantee string) (*entity.CredentialGrant, error) {
	var grant entity.CredentialGrant
	grant.ObjectId = objectId
	grant.Grantee = grantee
	ok, err := ds.engine.Cols("id", "allow", "grant_date", "expiration_date").
		Get(&grant)
	if err != nil {
		return nil, err
	}
	if !ok {
		return nil, nil
	}
	return &grant, nil
}

// CheckGrantOwner 校验授权是否属于拥有者
func (ds *DidService) CheckGrantOwner(grantId, owner string) (bool, error) {
	return ds.engine.Exist(&entity.CredentialGrant{
		Id:       grantId,
		OwnerDid: owner,
	})
}

// RevokeCredentialGrant 撤销授权
func (ds *DidService) RevokeCredentialGrant(grantId string) error {
	_, err := ds.engine.Id(grantId).Cols("allow").Update(&entity.CredentialGrant{})
	return err
}

// CheckDidOwnWallet 校验did是不是属于某钱包
func (ds *DidService) CheckDidOwnWallet(walletId, did string) bool {
	var (
		find string
	)
	ok, err := ds.engine.Table("did_document").
		Where("wallet_id = ? and did = ?", walletId, did).
		Cols("status").Get(&find)
	if err != nil {
		log.Errorf("find wallet and did err:%s", err.Error())
		return false
	}
	return ok && find == constant.DidValidStatus
}

// GetCredentialOwnerInfo 获取凭证信息
func (ds *DidService) GetCredentialOwnerInfo(id string) (wallet, did string) {
	var crendential entity.VerifiableCredential
	crendential.Id = id
	if _, err := ds.engine.Cols("owner_id", "owner_did").
		Get(&crendential); err != nil {
		log.Errorf("find owner info by id %s error %s", id, err.Error())
	}
	return crendential.OwnerId, crendential.OwnerDid
}
